package com.molichuxing.gateway.bff.financial.services.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.gateway.bff.dealer.entity.response.DealerVo;
import com.molichuxing.gateway.bff.dealer.services.impl.DealerBffServiceImpl;
import com.molichuxing.gateway.bff.financial.convertor.Convert;
import com.molichuxing.gateway.bff.financial.entity.request.modify.InvoiceInfoModifyStatusVo;
import com.molichuxing.gateway.bff.financial.entity.response.InvoiceInfoVo;
import com.molichuxing.gateway.bff.financial.services.InvoiceBffService;
import com.molichuxing.gateway.property.InvoiceApplyStatusEnum;
import com.molichuxing.services.business.dto.response.InvoiceInfoBizDto;
import com.molichuxing.services.business.service.InvoiceBizService;
import com.molichuxing.services.infrastructure.dto.request.create.InvoiceCreateDto;
import com.molichuxing.services.infrastructure.dto.response.UserDto;
import com.molichuxing.services.infrastructure.service.InvoiceInfoService;
import com.molichuxing.services.infrastructure.service.InvoiceService;
import com.molichuxing.services.infrastructure.service.UserService;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 发票相关bff
 *
 * @author zhaopenghui
 * @date 2019年9月23日
 */
@Service("invoiceBffService")
public class InvoiceBffServiceImpl implements InvoiceBffService {
    private static final Logger logger = LoggerFactory.getLogger(DealerBffServiceImpl.class);

    @Resource
    private InvoiceBizService invoiceBizService;
    @Resource
    private InvoiceInfoService invoiceInfoService;
    @Resource
    private InvoiceService invoiceService;
    @Resource
    private UserService userService;


    /**
     * 发票管理列表
     *
     * @param map
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public Paged<InvoiceInfoVo> getInvoiceInfoPage(Map<String, Object> map, Integer pageNum, Integer pageSize) throws Exception {
        Object realNameObj = map.get("realName");
        if (realNameObj != null) {
            String realName = ObjectCastUtil.castString(realNameObj);
            Integer userId = getUserIdByRealName(realName);
            if (null == userId) {
                Paged<InvoiceInfoVo> paged = new Paged<InvoiceInfoVo>();
                return getPageTab(paged);
            }
            map.put("userId", userId);
        }

        Paged<InvoiceInfoBizDto> invoiceInfoPage = invoiceBizService.getInvoiceInfoPage(map, pageNum, pageSize);
        if (null == invoiceInfoPage) {
            Paged<InvoiceInfoVo> paged = new Paged<InvoiceInfoVo>();
            return getPageTab(paged);
        }
        List<InvoiceInfoBizDto> invoiceInfoBizDtoList = invoiceInfoPage.getList();
        if (null == invoiceInfoBizDtoList) {
            Paged<InvoiceInfoVo> paged = new Paged<InvoiceInfoVo>();
            return getPageTab(paged);
        }

        Map<Integer, UserDto> userMap = getUserMap(invoiceInfoBizDtoList);
        List<InvoiceInfoVo> contractVoList = Convert.toInvoiceInfoVoList(invoiceInfoBizDtoList, userMap);
        Paged<InvoiceInfoVo> paged = new Paged<InvoiceInfoVo>(contractVoList, invoiceInfoPage.getTotal(), pageSize);
        return getPageTab(paged);
    }


    /**
     * 获取用户id
     *
     * @param realName
     * @return
     */
    private Integer getUserIdByRealName(String realName) {
        Integer userId = null;
        if (StringUtils.isNoneBlank(realName)) {
            UserDto userDto = userService.getUserByRealName(realName);
            if (userDto != null) {
                userId = userDto.getId();
            }
        }
        return userId;
    }

    /**
     * 获取用户map
     *
     * @param invoiceInfoBizDtoList
     * @return
     */
    private Map<Integer, UserDto> getUserMap(List<InvoiceInfoBizDto> invoiceInfoBizDtoList) {
        if (null == invoiceInfoBizDtoList || invoiceInfoBizDtoList.size() < 1) {
            return null;
        }

        List<Integer> userIdList = new ArrayList<>();
        for (InvoiceInfoBizDto invoiceInfoBizDto : invoiceInfoBizDtoList) {
            Integer userId = invoiceInfoBizDto.getUserId();
            if (null == userId) {
                continue;
            }
            userIdList.add(userId);
        }

        return userService.getUsers(userIdList);
    }

    /**
     * 获取分页tab值
     *
     * @return
     * @throws Exception
     */
    private Paged<InvoiceInfoVo> getPageTab(Paged<InvoiceInfoVo> paged) throws Exception {
        Map<Integer, Integer> statusCountMap = invoiceInfoService.getInvoiceCountByStatus();
        List<TabDto> tabList = new ArrayList<>();
        for (InvoiceApplyStatusEnum invoiceStatusEnum : InvoiceApplyStatusEnum.values()) {
            int value = invoiceStatusEnum.getValue();
            String name = invoiceStatusEnum.getName();
            Integer count = 0;
            if (null != statusCountMap && statusCountMap.size() > 0) {
                count = statusCountMap.get(value);
            }
            if (null == count) {
                count = 0;
            }

            TabDto tabDto = new TabDto();
            tabDto.setName(name);
            tabDto.setType(value);
            tabDto.setCount(count);
            tabList.add(tabDto);
        }
        return paged.setTab(tabList);
    }

    /**
     * 开票
     *
     * @param invoiceInfoModifyStatusVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean modifyInvoiceStatus(InvoiceInfoModifyStatusVo invoiceInfoModifyStatusVo) throws Exception {
        Integer invoiceInfoId = invoiceInfoModifyStatusVo.getInvoiceInfoId();
        return invoiceInfoService.modifyInvoiceStatus(invoiceInfoId, InvoiceApplyStatusEnum.HAS_MAKE_OUT.getValue());
    }

    @Override
    public Boolean initInvoiceData() throws Exception{
        List<InvoiceCreateDto> dataResult = invoiceService.selectOrderData();
        for(InvoiceCreateDto dto : dataResult) {
            invoiceService.createInvoice(dto);
        }


        List<InvoiceCreateDto> dataSubscribeResult = invoiceService.selectSubscribeOrderData();
        for(InvoiceCreateDto dto : dataSubscribeResult) {
            invoiceService.createInvoice(dto);
        }
        return true;
    }

}
